package gecko.dk;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

import static gecko.x.ByteX.hex;

/**
 * 东控门禁通讯协议
 *
 * @author 陈永佳 (yoojiachen@gmail.com)
 * @version 0.0.1
 */
public class Instr {

    public static final int DATA_SIZE = 32;
    public static final int EXT_DATA_SIZE = 20;

    public final byte DK_MAGIC; // 1
    public final byte FUN_ID; // 1
    public final short RESERVED; // 2
    public final int DEV_SN; // 4
    public final byte[] DATA; // 32
    public final int SEQ_ID; // 4
    public final byte[] EXT_DATA = new byte[EXT_DATA_SIZE];  // 20

    public Instr(byte FUN_ID, int DEV_SN, int SEQ_ID, byte[] data) {
        this.DK_MAGIC = 0x17;
        this.FUN_ID = FUN_ID;
        this.RESERVED = 0x00;
        this.DEV_SN = DEV_SN;
        this.SEQ_ID = SEQ_ID;
        this.DATA = data;
    }

    public Instr(byte[] bytes) {
        if (bytes.length != 64) {
            throw new IllegalArgumentException("未支持的DK品牌UDP数据包： INVALID_LENGTH:64, was: " + bytes.length);
        }
        final ByteBuffer buffer = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
        this.DK_MAGIC = buffer.get();
        this.FUN_ID = buffer.get();
        this.RESERVED = buffer.getShort();
        this.DEV_SN = buffer.getInt();
        this.DATA = new byte[DATA_SIZE];
        buffer.get(this.DATA);
        this.SEQ_ID = buffer.getInt();
        buffer.get(this.EXT_DATA);
    }

    public byte[] bytes() {
        final ByteBuffer buf = makeBuffer(64);
        buf.put(DK_MAGIC);
        buf.put(FUN_ID);
        buf.putShort(RESERVED);
        buf.putInt(DEV_SN);
        buf.put(DATA);
        buf.putInt(SEQ_ID);
        buf.put(EXT_DATA);
        return buf.array();
    }

    @Override
    public String toString() {
        return "Instr{" +
                "DK_MAGIC=" + hex(DK_MAGIC) +
                ", FUN_ID=" + hex(FUN_ID) +
                ", RESERVED=" + hex(RESERVED) +
                ", DEV_SN=" + hex(DEV_SN, false) +
                ", DATA=" + hex(DATA) +
                ", SEQ_ID=" + hex(SEQ_ID) +
                ", EXT_DATA=" + hex(EXT_DATA) +
                ", BYTES=" + hex(bytes()) +
                '}';
    }

    /**
     * 构建DK指令的Buffer
     *
     * @param capacity 容量
     * @return ByteBuffer
     */
    public static ByteBuffer makeBuffer(int capacity) {
        return ByteBuffer.allocate(capacity).order(ByteOrder.LITTLE_ENDIAN);
    }

    public static byte[] ip2Bytes(String ip) {
        try {
            return InetAddress.getByName(ip).getAddress();
        } catch (UnknownHostException e) {
            return new byte[]{0, 0, 0, 0};
        }
    }
}
